<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="shortcut icon" type="image/x-icon" href="./data/favicon.ico">
    <script type="module" charset="UTF-8" src="./libs/three.js/Three.js"></script>
    <script type="text/javascript" src="./libs/dat.gui/dat.gui.min.js"></script>
    <style>
        body {
            margin: 0px;
            overflow: hidden;
        }

        #statsdiv {
            width: 200px;
            background-color: rebeccapurple;
            overflow: hidden;
        }
    </style>
    <title>threejs-lesson-06</title>
</head>

<body>
    <div id="puidu-webgk-output"></div>
    <div id="statsdiv"></div>
    <script type="module">
        import * as THREE from "./libs/three.js/three.js"
        import Stats from "./libs/stats.js/Stats.js"

        //创建场景对象
        var scene = new THREE.Scene();
        //透视摄像机
        var prescamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        //相机位置
        prescamera.position.z = 35;
        prescamera.position.x = -30;
        prescamera.position.y = 45;
        //渲染器
        var renderer = new THREE.WebGLRenderer();

        //添加坐标轴
        var axes = new THREE.AxesHelper(50);
        axes.setColors(0xFF0000, 0x00FF00, 0x0000FF);
        scene.add(axes);
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.getElementById("puidu-webgk-output").appendChild(renderer.domElement)
        //创建渲染对象1
        var geometry = new THREE.BoxGeometry(5, 5, 5);
        var material = new THREE.MeshBasicMaterial({ color: 0xFF0000 });
        var cube = new THREE.Mesh(geometry, material);
        //告诉立方体需要投射阴影
        cube.castShadow = true;
        scene.add(cube)
        //创建渲染对象2
        var geometry2 = new THREE.BoxGeometry(5, 5, 5);
        var material2 = new THREE.MeshBasicMaterial({ color: 0xFFFF00 });
        var cube2 = new THREE.Mesh(geometry2, material2);
        cube2.castShadow = true;
        cube2.name = "cube2"
         scene.add(cube2)
        cube2.position.x = -10;
        //自定义集合体
        var mygeometry1 = new THREE.BufferGeometry();
        var vertices = new Float32Array([
            //底面 
            -5, 1, -5,
            -5, 1, -15,
            -15, 1, -15,
            -15, 1, -15,
            -15, 1, -5,
            -5, 1, -5,
            //侧面1
            -5, 1, -5,
            -5, 1, -15,
            -10, 20, -10,
            //侧面2
            -5, 1, -15,
            -15, 1, -15,
            -10, 20, -10,
            //3
            -15, 1, -15,
            -15, 1, -5,
            -10, 20, -10,
            //4
            -15, 1, -5,
            -5, 1, -5,
            -10, 20, -10,
        ]);
        var atrribute = new THREE.BufferAttribute(vertices, 3);
        mygeometry1.attributes.position = atrribute;
        var mymaterial = new THREE.MeshBasicMaterial({
            color: 0xFFAAAA,
            side: THREE.DoubleSide
        })
        var mymesh = new THREE.Mesh(mygeometry1, mymaterial);
        mymesh.castShadow = true;
        scene.add(mymesh);
        //自定义mesh添加线条
        var wireframe = new THREE.WireframeGeometry( mygeometry1 );

            var line = new THREE.LineSegments( wireframe );
            line.material.depthTest = false;
            line.material.opacity = 0.5;
            line.material.transparent = true;

            scene.add( line );


        //获取场景中对象
        // console.log(scene.children)
        var obj = scene.getObjectByName("cube2", true);
        // console.log(obj)


        //添加地面
        var ground = creatgroung(scene);
        //环境光
        creatAmbientLight(scene)
        //平行光
        //告诉渲染器需要阴影效果
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默认的是，没有设置的这个清晰 THREE.PCFShadowMap
        var directionalLight = new THREE.DirectionalLight("#ffffff");
        directionalLight.position.set(-40, 60, -20);

        directionalLight.shadow.camera.near = 0.1; //产生阴影的最近距离
        directionalLight.shadow.camera.far = 1000; //产生阴影的最远距离
        directionalLight.shadow.camera.left = -500; //产生阴影距离位置的最左边位置
        directionalLight.shadow.camera.right = 500; //最右边
        directionalLight.shadow.camera.top = 500; //最上边
        directionalLight.shadow.camera.bottom = -500; //最下面

        //这两个值决定使用多少像素生成阴影 默认512
        directionalLight.shadow.mapSize.height = 1024;
        directionalLight.shadow.mapSize.width = 1024;



        //告诉平行光需要开启阴影投射
        directionalLight.castShadow = true;

        scene.add(directionalLight);
        //帧数
        var stats = AddStats();
        //调节参数
        var ctrlObj = { rotationSpedd: 0.01, jumpSpeed: 0.01,positionX:-10,positionY:10,positionZ:0,rotationX:0,rotationY:0,rotationZ:0,
        traslationX:0,traslationY:0,traslationZ:0 ,isvsibel:true};
        var ctrlobj1 = new function () {
            this.createcube = function () {
                var geometryT = new THREE.BoxGeometry(6, 6, 6);
                var materialT = new THREE.MeshBasicMaterial({ color: 0x123456 });
                var cubeT = new THREE.Mesh(geometryT, materialT);
                cubeT.castShadow = true;
                cubeT.position.x = -(Math.random() * 10);
                cubeT.position.y = (Math.random() * 10);
                cubeT.position.z = (Math.random() * 10);
                scene.add(cubeT)
            }
        }

        var ctrl = new dat.GUI();
        ctrl.add(ctrlObj, "rotationSpedd", 0, 1);
        ctrl.add(ctrlObj, "jumpSpeed", 0, 1);
        ctrl.add(ctrlObj, "positionX", -20, 20);
        ctrl.add(ctrlObj, "positionY", -20, 20);
        ctrl.add(ctrlObj, "positionZ", -20, 20);

        ctrl.add(ctrlObj, "rotationX",  0, 7.29);
        ctrl.add(ctrlObj, "rotationY",  0,   7.29);
        ctrl.add(ctrlObj, "rotationZ",  0,   7.29);
        
        ctrl.add(ctrlObj, "traslationX",  -20, 20);
        ctrl.add(ctrlObj, "traslationY",  -20, 20);
        ctrl.add(ctrlObj, "traslationZ",  -20, 20);
        ctrl.add(ctrlObj, "isvsibel");

        ctrl.add(ctrlobj1, "createcube");

        //绑定
       

        prescamera.lookAt(scene.position)
        //场景渲染
        //renderer.render(scene, prescamera);
        renderScene();

        function creatgroung(para_scene) {
            var groundgeometry = new THREE.PlaneGeometry(100, 100);
            var groungmaterial = new THREE.MeshLambertMaterial({ color: 0xCCCCCC });
            var ground = new THREE.Mesh(groundgeometry, groungmaterial);
            ground.rotation.x = -0.5 * Math.PI;
            para_scene.add(ground);
            // 使平面就接收物体投掷过来的阴影
            ground.receiveShadow = true;

            return ground;
        };

        function creatAmbientLight(para_scene) {
            var ambienLight = new THREE.AmbientLight(0xAAAAAA)
            para_scene.add(ambienLight);
        };


        //场景渲染方法
        var gap = 0;
        function renderScene() {
            gap += ctrlObj.jumpSpeed;
            cubrotating(cube, ctrlObj.rotationSpedd);
            cube2.position.x=ctrlObj.positionX;
            cube2.position.y=ctrlObj.positionY;
            cube2.position.z=ctrlObj.positionZ;
            cube2.rotation.x=ctrlObj.rotationX;
            cube2.rotation.y=ctrlObj.rotationY;
            cube2.rotation.z=ctrlObj.rotationZ;
            cube2.translateX(ctrlObj.traslationX);
            cube2.translateY(ctrlObj.traslationY);
            cube2.translateZ(ctrlObj.traslationZ);
            cube2.visible =ctrlObj.isvsibel;
            //遍历场景中所有对象
            // scene.traverse(child => {
            //     if (child instanceof THREE.Mesh && child != ground) {
            //         cubrotating(child, ctrlObj.rotationSpedd);
            //     }
            // })
            cubjump(cube, gap);
            stats.update();

            window.requestAnimationFrame(renderScene);
            renderer.render(scene, prescamera);

        }
        //帧数统计
        function AddStats() {
            var stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.right = '0px';
            stats.domElement.style.width = '100px';
            stats.setMode(0);
            document.getElementById("statsdiv").appendChild(stats.domElement);
            return stats;
        }

        function cubrotating(param_geotry, speed) {
            param_geotry.rotation.x += speed;
            param_geotry.rotation.y += speed;
            param_geotry.rotation.z += speed;
        }
        function cubjump(param_geotry, speed) {
            speed = speed / Math.PI;
            param_geotry.position.x = 25 + (20 * (Math.sin(speed)));
            param_geotry.position.y = 6 + (20 * Math.abs((Math.cos(speed))));
            param_geotry.position.z = 6 + (-20 * Math.abs((Math.cos(speed))));
        }
        function removeFindCube(object) {
            if (object instanceof Mesh) {
                scene.remove(object);
            }
        }

        window.addEventListener("resize", onWindowResize, false);
        function onWindowResize() {
            prescamera.aspect = window.innerWidth / window.innerHeight;
            prescamera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }
    </script>
</body>

</html>